package com.jd.aop;

import com.jd.aop.anno.LogAnno;
import com.jd.aop.domain.Aop;
import com.jd.aop.service.AopService;
import com.jd.aop.util.IPAddressUtils;
import com.jd.org.domain.Department;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;

@Component
@Aspect
@Slf4j
public class PetHomeAop {
    @Autowired
    private AopService service;
    @Around("@annotation(com.jd.aop.anno.LogAnno)")
    public Object logAop(ProceedingJoinPoint pjp) throws Throwable {

        Department department = (Department) pjp.getArgs()[0];
        System.err.println("学生类" + department.getId());
        String d= "";
        if (department.getId()==null){
            d = "添加";
        }else {
            d = "修改";
        }
        long start = System.currentTimeMillis();
        String userIP = null;
        try {
            // 获取请求信息
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            // 获取请求用户IP
            userIP = IPAddressUtils.getIpAdrress(request);
            System.err.println("IP地址:" + userIP);
        } catch (Exception e) {
            log.error("获取request出错=>" + e.getMessage());
        }

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 调用pjp的api  methodSignature 对象能获取到当前的方法
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        // 根据methodSignature 获取到当前被我们自定义注解标识的方法对象
        Method method = methodSignature.getMethod();
        // method对象 能获取到当前方法上的注解 以及其他的属性
        String name = method.getName();
        Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
        // 获取到指定的注解 这里获取到得是我们自定义的注解
        LogAnno annotation = method.getAnnotation(LogAnno.class);

        // 通过 annotation 获取到注解里面的属性
        String des = annotation.des();
        log.info("method的getName值为：{}",name);
        log.info("declaredAnnotations:{}",declaredAnnotations);
        log.info("方法描述：{}",des);

//        Object[] args = pjp.getArgs();
//        Class clazz = annotation.clazz();
//        Class superclass = clazz.getSuperclass();
//        Optional<Object> first = Arrays.stream(args).filter(arg -> arg.getClass().equals(clazz)).findFirst();
//        Object o1 = first.get();
//        System.err.println(superclass);
//        Field id = superclass.getDeclaredField("id");
//        id.setAccessible(true);
//        Long idFiled = (Long) id.get(o1);
//        des = idFiled == null ? "添加" : "修改";

        // 不要 忘记 执行我们的业务方法
        Object proceed = pjp.proceed();
        long end = System.currentTimeMillis();
        System.err.println(new Aop(userIP,name,des,end-start));
        service.add(new Aop(userIP,name,d,end-start));
        return proceed;
    }
}
